home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / trace / tcpdump-2.2.1 / print-ospf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-29  |  13.3 KB  |  587 lines

  1. /*
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
  22.  */
  23. #ifndef lint
  24. static char rcsid[] =
  25.     "@(#) $Header: print-ospf.c,v 1.1 92/01/29 12:44:17 mccanne Exp $ (LBL)";
  26. #endif
  27.  
  28. #include <sys/param.h>
  29. #include <sys/socket.h>
  30. #include <netinet/in.h>
  31. #include <netinet/in_systm.h>
  32. #include <netinet/ip.h>
  33. #include <netinet/ip_var.h>
  34.  
  35. #include <errno.h>
  36. #include <ctype.h>
  37.  
  38. #include "ospf.h"
  39. #include "interface.h"
  40. #include "addrtoname.h"
  41.  
  42. #ifndef    __GNUC__
  43. #define    inline
  44. #endif
  45.  
  46. #if    !defined(__STDC__) && !defined(const)
  47. #define    const
  48. #endif    /* !defined(__STDC__) && !defined(const) */
  49.  
  50. struct bits {
  51.     u_long bit;
  52.     const char *str;
  53. };
  54.  
  55. static const struct bits ospf_option_bits[] = {
  56.     OSPF_OPTION_T,    "T",
  57.     OSPF_OPTION_E,    "E",
  58.     OSPF_OPTION_MC,    "MC",
  59.     0,            (char *) 0
  60. };
  61.  
  62. static const struct bits ospf_rla_flag_bits[] = {
  63.     RLA_FLAG_B,        "B",
  64.     RLA_FLAG_E,        "E",
  65.     RLA_FLAG_W1,    "W1",
  66.     RLA_FLAG_W2,    "W2",
  67.     0,            (char *) 0
  68. };
  69.  
  70. static const char *ospf_types[OSPF_TYPE_MAX] = {
  71.   (char *) 0,
  72.   "hello",
  73.   "dd",
  74.   "ls_req",
  75.   "ls_upd",
  76.   "ls_ack"
  77. };
  78.  
  79. static inline void
  80. ospf_print_seqage(seq, us)
  81. register u_long seq;
  82. register time_t us;
  83. {
  84.     register time_t sec = us % 60;
  85.     register time_t mins = (us / 60) % 60;
  86.     register time_t hour = us/3600;
  87.  
  88.     printf(" S %X age ",
  89.        seq);
  90.     if (hour) {
  91.     printf("%d:%02d:%02d",
  92.            hour,
  93.            mins,
  94.            sec);
  95.     } else if (mins) {
  96.     printf("%d:%02d",
  97.            mins,
  98.            sec);
  99.     } else {
  100.     printf("%d",
  101.            sec);
  102.     }
  103. }
  104.  
  105.  
  106. static inline void
  107. ospf_print_bits(bp, options)
  108. register struct bits *bp;
  109. register u_char options;
  110. {
  111.     char sep = ' ';
  112.  
  113.     do {
  114.     if (options & bp->bit) {
  115.         printf("%c%s",
  116.            sep,
  117.            bp->str);
  118.         sep = '/';
  119.     }
  120.     } while ((++bp)->bit) ;
  121. }
  122.  
  123.  
  124. #define    LS_PRINT(lsp, type) switch (type) { \
  125.     case LS_TYPE_ROUTER: \
  126.     printf(" rtr %s ", ipaddr_string(&lsp->ls_router)); break; \
  127.     case LS_TYPE_NETWORK: \
  128.     printf(" net dr %s if %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \
  129.     case LS_TYPE_SUM_IP: \
  130.     printf(" sum %s abr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  131.     case LS_TYPE_SUM_ABR: \
  132.     printf(" abr %s rtr %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \
  133.     case LS_TYPE_ASE: \
  134.     printf(" ase %s asbr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  135.     case LS_TYPE_GROUP: \
  136.     printf(" group %s rtr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  137.     }
  138.  
  139. static int
  140. ospf_print_lshdr(lshp, end)
  141. register struct lsa_hdr *lshp;
  142. caddr_t end;
  143. {
  144.     if ((caddr_t) (lshp + 1) > end) {
  145.     return 1;
  146.     }
  147.     
  148.     printf(" {");
  149.  
  150.     if (!lshp->ls_type || lshp->ls_type >= LS_TYPE_MAX) {
  151.     printf(" ??LS type %d?? }",
  152.            lshp->ls_type);
  153.     return 1;
  154.     }
  155.  
  156.     ospf_print_bits(ospf_option_bits, lshp->ls_options);
  157.     ospf_print_seqage(ntohl(lshp->ls_seq),
  158.               ntohs(lshp->ls_age));
  159.  
  160.     LS_PRINT(lshp, lshp->ls_type);
  161.  
  162.     return 0;
  163. }
  164.  
  165.  
  166. /*
  167.  * Print a single link state advertisement.  If truncated return 1, else 0.
  168.  */
  169.  
  170. static int
  171. ospf_print_lsa(lsap, end)
  172. register struct lsa *lsap;
  173. caddr_t    end;
  174. {
  175.     register caddr_t ls_end;
  176.     struct rlalink *rlp;
  177.     struct tos_metric *tosp;
  178.     struct in_addr *ap;
  179.     struct aslametric *almp;
  180.     struct mcla *mcp;
  181.     u_long *lp;
  182.     int j, k;
  183.  
  184.     if (ospf_print_lshdr(&lsap->ls_hdr, end)) {
  185.     return 1;
  186.     }
  187.  
  188.     ls_end = (caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length);
  189.     
  190.     if (ls_end > end) {
  191.     printf(" }");
  192.     return 1;
  193.     }
  194.  
  195.     switch (lsap->ls_hdr.ls_type) {
  196.     case LS_TYPE_ROUTER:
  197.     ospf_print_bits(ospf_rla_flag_bits, lsap->lsa_un.un_rla.rla_flags);
  198.  
  199.     j = ntohs(lsap->lsa_un.un_rla.rla_count);
  200.     rlp = lsap->lsa_un.un_rla.rla_link;
  201.     while (j--) {
  202.         struct rlalink *rln = (struct rlalink *) ((caddr_t) (rlp + 1) + ((rlp->link_toscount) * sizeof (struct tos_metric)));
  203.  
  204.         if ((caddr_t) rln > ls_end) {
  205.         break;
  206.         }
  207.         printf(" {");
  208.  
  209.         switch (rlp->link_type) {
  210.         case RLA_TYPE_VIRTUAL:
  211.         printf(" virt");
  212.         /* Fall through */
  213.         
  214.         case RLA_TYPE_ROUTER:
  215.         printf(" nbrid %s if %s",
  216.                ipaddr_string(&rlp->link_id),
  217.                ipaddr_string(&rlp->link_data));
  218.         break;
  219.  
  220.         case RLA_TYPE_TRANSIT:
  221.         printf(" dr %s if %s",
  222.                ipaddr_string(&rlp->link_id),
  223.                ipaddr_string(&rlp->link_data));
  224.         break;
  225.  
  226.         case RLA_TYPE_STUB:
  227.         printf(" net %s mask %s",
  228.                ipaddr_string(&rlp->link_id),
  229.                ipaddr_string(&rlp->link_data));
  230.         break;
  231.  
  232.         default:
  233.         printf(" ??RouterLinksType %d?? }",
  234.                rlp->link_type);
  235.         return 0;
  236.         }
  237.         printf(" tos 0 metric %d",
  238.            ntohs(rlp->link_tos0metric));
  239.         tosp = (struct tos_metric *) ((sizeof rlp->link_tos0metric) + (caddr_t) rlp);
  240.         for (k = 0; k < rlp->link_toscount; k++, tosp++) {
  241.         printf(" tos %d metric %d",
  242.                ntohs(tosp->tos_type),
  243.                ntohs(tosp->tos_metric));
  244.         }
  245.         printf(" }");
  246.         rlp = rln;
  247.     }
  248.     break; 
  249.  
  250.     case LS_TYPE_NETWORK: 
  251.     printf(" mask %s rtrs",
  252.            ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
  253.     for (ap = lsap->lsa_un.un_nla.nla_router;
  254.          (caddr_t) (ap + 1) <= ls_end;
  255.          ap++) {
  256.         printf(" %s",
  257.            ipaddr_string(ap));
  258.     }
  259.     break; 
  260.  
  261.     case LS_TYPE_SUM_IP: 
  262.     printf(" mask %s",
  263.            ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
  264.     /* Fall through */
  265.  
  266.     case LS_TYPE_SUM_ABR:
  267.  
  268.     for (lp = lsap->lsa_un.un_sla.sla_tosmetric;
  269.          (caddr_t) (lp + 1) <= ls_end;
  270.          lp++) {
  271.         u_long ul = ntohl(*lp);
  272.  
  273.         printf(" tos %d metric %d",
  274.            (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
  275.            ul & SLA_MASK_METRIC);
  276.     }
  277.     break;
  278.  
  279.     case LS_TYPE_ASE:
  280.     printf(" mask %s",
  281.            ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
  282.  
  283.     for (almp = lsap->lsa_un.un_asla.asla_metric;
  284.          (caddr_t) (almp + 1) <= ls_end;
  285.          almp++) {
  286.         u_long ul = ntohl(almp->asla_tosmetric);
  287.  
  288.         printf(" type %d tos %d metric %d",
  289.            (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
  290.            (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS,
  291.            (ul & ASLA_MASK_METRIC));
  292.         if (almp->asla_forward.s_addr) {
  293.         printf(" forward %s",
  294.                ipaddr_string(&almp->asla_forward));
  295.         }
  296.         if (almp->asla_tag.s_addr) {
  297.         printf(" tag %s",
  298.                ipaddr_string(&almp->asla_tag));
  299.         }
  300.     }
  301.     break;
  302.  
  303.     case LS_TYPE_GROUP:
  304.     /* Multicast extensions as of 23 July 1991 */
  305.     for (mcp = lsap->lsa_un.un_mcla;
  306.          (caddr_t) (mcp + 1) <= ls_end;
  307.          mcp++) {
  308.         switch (ntohl(mcp->mcla_vtype)) {
  309.         case MCLA_VERTEX_ROUTER:
  310.         printf(" rtr rtrid %s",
  311.                ipaddr_string(&mcp->mcla_vid));
  312.         break;
  313.  
  314.         case MCLA_VERTEX_NETWORK:
  315.         printf(" net dr %s",
  316.                ipaddr_string(&mcp->mcla_vid));
  317.         break;
  318.  
  319.         default:
  320.         printf(" ??VertexType %d??",
  321.                ntohl(mcp->mcla_vtype));
  322.         break;
  323.         }
  324.     }
  325.     }
  326.  
  327.     printf(" }");
  328.     return 0;
  329. }
  330.  
  331.  
  332. void
  333. ospf_print(dat, length, ip)
  334. u_char *dat;
  335. int length;
  336. struct ip *ip;
  337. {
  338.     register struct ospfhdr *op = (struct ospfhdr *) dat;
  339.     register caddr_t end = (caddr_t)snapend;
  340.     register struct lsa *lsap;
  341.     register struct lsa_hdr *lshp;
  342.     char sep;
  343.     int i, j;
  344.     struct in_addr *ap;
  345.     struct lsr *lsrp;
  346.  
  347.     /* Print the source and destination address    */
  348.     (void) printf(" %s > %s:",
  349.           ipaddr_string(&ip->ip_src),
  350.           ipaddr_string(&ip->ip_dst));
  351.  
  352.     if ((caddr_t) (&op->ospf_len + 1) > end) {
  353.     goto trunc_test;
  354.     }
  355.  
  356.     /* If the type is valid translate it, or just print the type */
  357.     /* value.  If it's not valid, say so and return */
  358.     if (op->ospf_type || op->ospf_type < OSPF_TYPE_MAX) {
  359.     printf(" OSPFv%d-%s %d:",
  360.            op->ospf_version,
  361.            ospf_types[op->ospf_type],
  362.            length);
  363.     } else {
  364.     printf(" ospf-v%d-??type %d?? %d:",
  365.            op->ospf_version,
  366.            op->ospf_type,
  367.            length);
  368.     return;
  369.     }
  370.  
  371.     if (length != ntohs(op->ospf_len)) {
  372.     printf(" ??len %d??",
  373.            ntohs(op->ospf_len));
  374.     goto trunc_test;
  375.     }
  376.     
  377.     if ((caddr_t) (&op->ospf_routerid + 1) > end) {
  378.     goto trunc_test;
  379.     }
  380.     
  381.     /* Print the routerid if it is not the same as the source */
  382.     if (ip->ip_src.s_addr != op->ospf_routerid.s_addr) {
  383.     printf(" rtrid %s",
  384.            ipaddr_string(&op->ospf_routerid));
  385.     }
  386.  
  387.     if ((caddr_t) (&op->ospf_areaid + 1) > end) {
  388.     goto trunc_test;
  389.     }
  390.  
  391.     if (op->ospf_areaid.s_addr) {
  392.     printf(" area %s",
  393.            ipaddr_string(&op->ospf_areaid));
  394.     } else {
  395.     printf(" backbone");
  396.     }
  397.  
  398.     if ((caddr_t) (op->ospf_authdata + OSPF_AUTH_SIZE) > end) {
  399.     goto trunc_test;
  400.     }
  401.  
  402.     if (vflag) {
  403.     /* Print authentication data (should we really do this?) */
  404.     switch (ntohs(op->ospf_authtype)) {
  405.     case OSPF_AUTH_NONE:
  406.         break;
  407.  
  408.     case OSPF_AUTH_SIMPLE:
  409.         printf(" auth ");
  410.         j = 0;
  411.         for (i = 0; i < sizeof (op->ospf_authdata); i++) {
  412.         if (!isprint(op->ospf_authdata[i])) {
  413.             j = 1;
  414.             break;
  415.         }
  416.         }
  417.         if (j) {
  418.         /* Print the auth-data as a string of octets */
  419.         printf("%s.%s",
  420.                ipaddr_string((struct in_addr *) op->ospf_authdata),
  421.                ipaddr_string((struct in_addr *) &op->ospf_authdata[sizeof (struct in_addr)]));
  422.         } else {
  423.         /* Print the auth-data as a text string */
  424.         printf("'%.8s'",
  425.                op->ospf_authdata);
  426.         }
  427.         break;
  428.  
  429.     default:
  430.         printf(" ??authtype-%d??",
  431.            ntohs(op->ospf_authtype));
  432.         return;
  433.     }
  434.     }
  435.  
  436.  
  437.     /* Do rest according to version.    */
  438.     switch (op->ospf_version) {
  439.     case 2:
  440.         /* ospf version 2    */
  441.     switch (op->ospf_type) {
  442.     case OSPF_TYPE_UMD:        /* Rob Coltun's special monitoring packets; do nothing    */
  443.         break;
  444.  
  445.     case OSPF_TYPE_HELLO:
  446.         if ((caddr_t) (&op->ospf_hello.hello_deadint + 1) > end) {
  447.         break;
  448.         }
  449.         if (vflag) {
  450.         ospf_print_bits(ospf_option_bits, op->ospf_hello.hello_options);
  451.         printf(" mask %s int %d pri %d dead %d",
  452.                ipaddr_string(&op->ospf_hello.hello_mask),
  453.                ntohs(op->ospf_hello.hello_helloint),
  454.                op->ospf_hello.hello_priority,
  455.                ntohl(op->ospf_hello.hello_deadint));
  456.         }
  457.  
  458.         if ((caddr_t) (&op->ospf_hello.hello_dr + 1) > end) {
  459.         break;
  460.         }
  461.         if (op->ospf_hello.hello_dr.s_addr) {
  462.         printf(" dr %s",
  463.                ipaddr_string(&op->ospf_hello.hello_dr));
  464.         }
  465.  
  466.         if ((caddr_t) (&op->ospf_hello.hello_bdr + 1) > end) {
  467.         break;
  468.         }
  469.         if (op->ospf_hello.hello_bdr.s_addr) {
  470.         printf(" bdr %s",
  471.                ipaddr_string(&op->ospf_hello.hello_bdr));
  472.         }
  473.  
  474.         if (vflag) {
  475.         if ((caddr_t) (op->ospf_hello.hello_neighbor + 1) > end) {
  476.             break;
  477.         }
  478.         printf(" nbrs");
  479.         for (ap = op->ospf_hello.hello_neighbor;
  480.              (caddr_t) (ap + 1) <= end;
  481.              ap++) {
  482.             printf(" %s",
  483.                ipaddr_string(ap));
  484.         }
  485.         }
  486.         break;            /*  HELLO    */
  487.  
  488.     case OSPF_TYPE_DB:
  489.         if ((caddr_t) (&op->ospf_db.db_seq + 1) > end) {
  490.         break;
  491.         }
  492.         ospf_print_bits(ospf_option_bits, op->ospf_db.db_options);
  493.         sep = ' ';
  494.         if (op->ospf_db.db_flags & OSPF_DB_INIT) {
  495.         printf("%cI",
  496.                sep);
  497.         sep = '/';
  498.         }
  499.         if (op->ospf_db.db_flags & OSPF_DB_MORE) {
  500.         printf("%cM",
  501.                sep);
  502.         sep = '/';
  503.         }
  504.         if (op->ospf_db.db_flags & OSPF_DB_MASTER) {
  505.         printf("%cMS",
  506.                sep);
  507.         sep = '/';
  508.         }
  509.         printf(" S %X",
  510.            ntohl(op->ospf_db.db_seq));
  511.  
  512.         if (vflag) {
  513.         /* Print all the LS adv's */
  514.         lshp = op->ospf_db.db_lshdr;
  515.  
  516.         while (!ospf_print_lshdr(lshp, end)) {
  517.             printf(" }");
  518.             lshp++;
  519.         }
  520.         }
  521.         break;
  522.  
  523.     case OSPF_TYPE_LSR:
  524.         if (vflag) {
  525.         for (lsrp = op->ospf_lsr; (caddr_t) (lsrp+1) <= end; lsrp++) {
  526.             long type;
  527.  
  528.             if ((caddr_t) (lsrp + 1) > end) {
  529.             break;
  530.             }
  531.  
  532.             printf(" {");
  533.             if (!(type = lsrp->ls_type) || type >= LS_TYPE_MAX) {
  534.             printf(" ??LinkStateType %d }",
  535.                    type);
  536.             printf(" }");
  537.             break;
  538.             }
  539.  
  540.             LS_PRINT(lsrp, type);
  541.             printf(" }");
  542.         }
  543.         }
  544.         break;
  545.  
  546.     case OSPF_TYPE_LSU:
  547.         if (vflag) {
  548.         lsap = op->ospf_lsu.lsu_lsa;
  549.         i = ntohl(op->ospf_lsu.lsu_count);
  550.  
  551.         while (i-- &&
  552.                !ospf_print_lsa(lsap, end)) {
  553.             lsap = (struct lsa *) ((caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length));
  554.         }
  555.         }
  556.         break;
  557.  
  558.  
  559.     case OSPF_TYPE_LSA:
  560.         if (vflag) {
  561.         lshp = op->ospf_lsa.lsa_lshdr;
  562.  
  563.         while (!ospf_print_lshdr(lshp, end)) {
  564.             printf(" }");
  565.             lshp++;
  566.         }
  567.         break;
  568.         }
  569.     }            /* end switch on v2 packet type    */
  570.     break;
  571.  
  572.     default:
  573.     printf(" ospf [version %d]",
  574.            op->ospf_version);
  575.     break;
  576.     }                    /* end switch on version    */
  577.  
  578.   trunc_test:
  579.     if ((snapend - dat) < length) {
  580.     printf(" [|]");
  581.     }
  582.  
  583.     return;                /* from ospf_print    */
  584. }
  585.  
  586.  
  587.